<?php

class Directorio {

  private $ruta = -1;
  private $rutaPadre = -1;  
  private $nomRecursos = -1;
  private $archivos = -1;
  private $subDirectorios = -1;
  private $numArchivos = -1;
  private $numSubDirectorios =-1;

/**
 * Clase que representa un directorio
 *
 * @param string $ruta     Ej: 'nomDirectorio' | 'nomDirectorio/'
 *                         ContraEj: '/nomDirectorio'
 *
 * @author Marco Rodas
  */
  function  __construct($ruta) {
      if(is_dir($ruta)){
          $this->ruta = $ruta;          
          $this->nomRecursos = scandir($ruta);
          $this->nombre = basename($ruta);
      }
      else{
          throw new Exception("La ruta ".$ruta." no corresponde a un directorio válido.");
      }
      clearstatcache();
  }
/**
 * Devuelve el nombre del directorio
 * @author Marco Rodas
 */
  public function nombre(){
      return $this->nombre;
  }
 /**
  * @return string Devuelve la ruta completa del directorio padre, si no tiene devuelve cadena vacia.
  * @author Marco Rodas
  */
  public function rutaPadre(){
      if($this->rutaPadre == -1){
          $this->rutaPadre = dirname($this->ruta);
          if(($this->rutaPadre == '.') or ($this->rutaPadre == '\\')){
              $this->rutaPadre='';
          }
      }
      return $this->rutaPadre;
  }
  
  private function obtenerRecursos(){
      $this->archivos = array();
      $this->subDirectorios = array();
      if(!empty ($this->nomRecursos)){
          foreach ($this->nomRecursos as $nomRecurso) {
              if ($nomRecurso != "." && $nomRecurso != ".."){
                  $rutaTemp = $this->ruta."/".$nomRecurso;
                  if(is_dir($rutaTemp)){
                      $this->subDirectorios[] = new Directorio($rutaTemp);
                  }
                  else{
                      if(is_file($rutaTemp)){
                          $this->archivos[] = new Archivo($rutaTemp);
                      }
                  }
              }
          }
      }
  }
  /**
   * @return array Arreglo de objetos tipo Archivo
   */
  public function archivos(){
      if($this->archivos == -1 && $this->subDirectorios==-1 ){
          $this->obtenerRecursos();
      }
      return $this->archivos;
  }
  /**
   * @return array Arreglo de objetos tipo Directorio
   */
  public function subDirectorios(){
      if($this->archivos == -1 && $this->subDirectorios==-1 ){
          $this->obtenerRecursos();
      }
      return $this->subDirectorios;
  }
  /**
   * @return int Numero de archivos que contiene el directorio
   */
  public function numArchivos(){
      if($this->numArchivos==-1){
          $this->numArchivos = count($this->archivos());
      }
      return $this->numArchivos;
  }
  /**
   * @return int Numero de subdirectorios que contiene el directorio
   */
  public function numSubDirectorios(){
      if($this->numSubDirectorios==-1){
          $this->numSubDirectorios = count($this->subDirectorios());
      }
      return $this->numSubDirectorios;
  }  
  /** Busca archivos dentro del directorio actual que coincidan con el nombre dado.
   * Puede usar los comodines *.*, *.ext, nombre.*
   * @param string $nomArchivo Nombre del archivo incluida la extension si tiene alguna
   * @return mixed Devuelve falso si el nombre del archivo no es valido o si no existe ninguna coincidencia, en caso afirmativo devuelve uno o varios archivos en un arreglo.
   */
  public function buscarArchivo($nomArchivo){
      $esNomArchValido = strpos($nomArchivo, '/')===false and strpos($nomArchivo, '\\')===false;
      if($esNomArchValido){
          if($this->numArchivos()==0){ //Si no hay archivos
              return false;
          }
          $infoArch = pathinfo($nomArchivo);
          $nombre=$infoArch['filename'];
          $extension=(strpos($nomArchivo, '.')===false)?(''):($infoArch['extension']);
          if($nombre == '*' and $extension == '*'){ //*.* Todos los archivos
              return $this->archivos();
          }
          $resultados = array();          
          foreach ($this->archivos as $archivo) {
              // nombre.ext | nombre
              // Coincidencia perfecta
              if($extension == $archivo->extension() and $nombre == $archivo->nombre()){ 
                  $resultados[] = $archivo;
                  return $resultados;
              }
              // nombre.*
              elseif($extension == '*' and $nombre == $archivo->nombre()){
                  $resultados[] = $archivo;
              }
              // *.ext
              elseif($nombre == '*' and $extension == $archivo->extension()){
                  $resultados[] = $archivo;
              }
          }
          return (count($resultados)==0)?(false):($resultados);
      }
      return false;
  }

}
?>
